using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using System.IO.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using OfficeXml;
using Microsoft.SharePoint.Client;
using System.Security;
using System.Xml;
using Microsoft.SharePoint.Client.Taxonomy;
using Microsoft.SharePoint.Client.Search.Query;
using System.Linq;

namespace CoolStuff
{
    public partial class BrowserForm : System.Windows.Forms.Form
    {
        ClientContext ctx;
        TweetData td;
        string id;
        SharePointOnlineCredentials creds;
        Util util = new Util();

        public BrowserForm()
        {
            InitializeComponent();

            webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);

            string password = Util.O365Password;
            SecureString ss = new SecureString();
            foreach (char c in password.ToCharArray())
            {
                ss.AppendChar(c);
            }

            //upload the document to O365
            creds = new SharePointOnlineCredentials(Util.O365Username, ss);

        }

        new public void Dispose()
        {
            this.webBrowser1.Dispose();
            base.Dispose();
        }

        PicDoc picDoc = null;

        public PicDoc CurDoc
        {
            get { return picDoc; }
            set { picDoc = value; }
        }
        /// <summary>
        /// This method calls starts download of the page .
        /// </summary>
        /// <param name="url"></param>
        public void getImageFromUrl(string url, TweetData td)
        {
            completed = false;
            this.td = td;
            this.id = td.Id;

            try
            {
                //this.webBrowser1.Url = new Uri(url);
                this.webBrowser1.Navigate(url);

                while (!completed)
                {
                    Application.DoEvents();
                    Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        bool completed;

        /// <summary>
        /// This event handler is called after document is loaded in browser.
        /// We copy content of the invisible browser to new bitmap and pass it to PicDoc object which in turn will fire refreshPicture event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void webBrowser1_DocumentCompleted(Object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (completed)
                return;

            try
            {
                /*
                mshtml.IHTMLDocument2 docs2 = (mshtml.IHTMLDocument2)webBrowser1.Document.DomDocument;
                mshtml.IHTMLDocument3 docs3 = (mshtml.IHTMLDocument3)webBrowser1.Document.DomDocument;
                mshtml.IHTMLElement2 body2 = (mshtml.IHTMLElement2)docs2.body;
                mshtml.IHTMLElement2 root2 = (mshtml.IHTMLElement2)docs3.documentElement;

                int width = Math.Max(body2.scrollWidth, root2.scrollWidth);
                int height = Math.Max(root2.scrollHeight, body2.scrollHeight);
                */

                // Resize the control to the exact size to display the page. Also, make sure scroll bars are disabled                
                int width = webBrowser1.Document.Body.ScrollRectangle.Width;
                int height = webBrowser1.Document.Body.ScrollRectangle.Height;

                webBrowser1.Width = width;
                webBrowser1.Height = height;

                Bitmap docImage = new Bitmap(width, height);
                webBrowser1.DrawToBitmap(docImage, new Rectangle(webBrowser1.Location.X, webBrowser1.Location.Y, width, height));
                docImage.Save("c:\\temp\\" + this.id + ".png");

                string filename = "C:\\temp\\" + this.id + ".docx";

                CreateEmptyDoc(filename);

                //generate a word doc                
                Package pkg = Package.Open(filename, FileMode.Open);

                if (pkg != null)
                {
                    AddImageIntoWord(pkg, 14, 14, System.IO.File.ReadAllBytes("C:\\temp\\" + this.id + ".png"));
                    pkg.Close();
                }

                OfficeXml.wdocument doc = new wdocument();
                wbody body = new wbody();
                CreateWordDocumentBody(out doc, out body);

                //CreateEmptyDoc(filename);
                body.Wps.Add(CreatePForImage("c:\\temp\\" + this.id + ".png", 1, width, height));                

                doc.Wbody = body;
                string document = doc.SerializeToXml().Replace("type=", "w:type=").Replace("val=", "w:val=");
                document = document.Replace("&quot;", "\"");
                ReplaceDocument(filename, document);

                
                //string authCookie = creds.GetAuthenticationCookie(new Uri("https://cjg.sharepoint.com"));

                ctx = new Microsoft.SharePoint.Client.ClientContext("https://cjg.sharepoint.com");
                ctx.Credentials = creds;

                List list = ctx.Web.Lists.GetByTitle("Twitter");
                ctx.Load(list.RootFolder);
                ctx.ExecuteQuery();
 
                FileInfo info = new System.IO.FileInfo(filename);
                byte[] fileBytes = System.IO.File.ReadAllBytes(filename);
                FileCreationInformation fileCreateInfo = new FileCreationInformation();                
                fileCreateInfo.Content = fileBytes;                
                fileCreateInfo.Url = list.RootFolder.ServerRelativeUrl + "/" + td.TwitterId + "-" + info.Name;
                fileCreateInfo.Overwrite = true;
                Microsoft.SharePoint.Client.File file = list.RootFolder.Files.Add(fileCreateInfo);                
                ctx.Load(file.ListItemAllFields);
                ctx.ExecuteQuery();                

                SetDates(list, file.ListItemAllFields.Id);                

                //reset the site web version for search index...
                Web w = ctx.Web;
                ctx.Load(w);
                ctx.Load(w.ListTemplates);
                ctx.ExecuteQuery();

                //CreateTwitterList(w);
                //SetProperty(w, "chris", "givens");
                //SetProperty(w, "vti_searchversion", "1");

            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
            }

            completed = true;
        }

        public void CreateTwitterList(Web web)
        {
            ListCreationInformation info = new ListCreationInformation();
            info.Title = "Twitter2";
            ListTemplate listTemplate = web.ListTemplates.First(listTemp => listTemp.Name == "Document Library");
            info.TemplateFeatureId = listTemplate.FeatureId;
            info.TemplateType = listTemplate.ListTemplateTypeKind;
            info.Description = "Twitter2";
            List list = web.Lists.Add(info);
            ctx.ExecuteQuery();            

            Microsoft.SharePoint.Client.Taxonomy.TaxonomySession ts = TaxonomySession.GetTaxonomySession(ctx);
            TermSetCollection termSet = ts.GetTermSetsByName("Twitter", 1033);
            TermSet t = termSet.GetByName("Twitter");            
            ctx.Load(t);
            ctx.Load(t.TermStore);
            ctx.ExecuteQuery();

            Field mentionsField = list.Fields.AddFieldAsXml("<Field DisplayName='Mentions' Type='User' />", true, AddFieldOptions.DefaultValue);
            Field hashtagsField = list.Fields.AddFieldAsXml("<Field DisplayName='Hashtags' Type='TaxonomyFieldTypeMulti' />", true, AddFieldOptions.DefaultValue);

            TaxonomyField field = ctx.CastTo<TaxonomyField>(hashtagsField);
            field.SspId = t.TermStore.Id;
            field.TermSetId = t.Id;
            field.TargetTemplate = string.Empty;
            field.AllowMultipleValues = true;
            field.CreateValuesInEditForm = true;
            field.Open = true;
            field.AnchorId = Guid.Empty;
            field.Group = "Taxonomy Fields";
            field.UpdateAndPushChanges(true);

            Field twitterIdField = list.Fields.AddFieldAsXml("<Field DisplayName='TwitterId' Type='Text' />", true, AddFieldOptions.DefaultValue);
            Field tweetDateField = list.Fields.AddFieldAsXml("<Field DisplayName='TweetDate' Type='DateTime' />", true, AddFieldOptions.DefaultValue);
            Field styleField = list.Fields.AddFieldAsXml("<Field DisplayName=\"TweetText\" Type=\"Note\" RestrictedMode=\"TRUE\" RichText=\"TRUE\" AllowHyperLink=\"TRUE\" RichTextMode=\"FullHtml\" RowOrdinal=\"0\" Required=\"FALSE\" EnforceUniqueValues=\"FALSE\" Indexed=\"FALSE\" NumLines=\"6\" IsolateStyles=\"TRUE\" AppendOnly=\"FALSE\" />", true, AddFieldOptions.DefaultValue);
            list.Update();
            ctx.ExecuteQuery();
        }

        public Guid CreateTerm(string term)
        {
            Microsoft.SharePoint.Client.Taxonomy.TaxonomySession ts = TaxonomySession.GetTaxonomySession(ctx);            
            TermSetCollection termSet = ts.GetTermSetsByName("Twitter", 1033);
            TermSet t = termSet.GetByName("Twitter");            
            Term mmsTerm = t.CreateTerm(term, 1033, Guid.NewGuid());

            try
            {
                ctx.Load(t.Terms);
                ctx.Load(mmsTerm);
                ctx.ExecuteQuery();
            }
            catch(Exception ex)
            {
                //return Get(term,Guid.Parse("94556b5e-54ba-469c-9143-55ed148953a4"));
                return GetTerm(term);
            }

            return mmsTerm.Id;
        }

        public Guid GetTerm(string term)
        {
            Microsoft.SharePoint.Client.Taxonomy.TaxonomySession ts = TaxonomySession.GetTaxonomySession(ctx);
            TermSetCollection termSet = ts.GetTermSetsByName("Twitter", 1033);
            TermSet t = termSet.GetByName("Twitter");
            ctx.Load(t);
            ctx.Load(t.Terms);
            ctx.ExecuteQuery();
            
            
            LabelMatchInformation info = new LabelMatchInformation(ctx);
            info.TermLabel = term;
            //info.DefaultLabelOnly = true;
            info.TrimUnavailable = true;
            info.Lcid = 1033;
            //info.ResultCollectionSize = 1;
            TermCollection terms = t.GetTerms(info);
            ctx.Load(terms);
            ctx.ExecuteQuery();

            if (terms.Count == 0)
            {
                return CreateTerm(term);
            }
            else
            {
                return terms[0].Id;
            }

            return Guid.Empty;
        }

        public Guid GetTermIdForTerm(string term, Guid termSetId)
        {
            Guid termId = Guid.Empty;

            TaxonomySession tSession = TaxonomySession.GetTaxonomySession(ctx);
            TermStore ts = tSession.GetDefaultSiteCollectionTermStore();
            TermSet tset = ts.GetTermSet(termSetId);

            LabelMatchInformation lmi = new LabelMatchInformation(ctx);

            lmi.Lcid = 1033;
            lmi.TrimUnavailable = true;
            lmi.TermLabel = term;

            TermCollection termMatches = tset.GetTerms(lmi);
            ctx.Load(tSession);
            ctx.Load(ts);
            ctx.Load(tset);
            ctx.Load(termMatches);

            ctx.ExecuteQuery();

            if (termMatches != null && termMatches.Count > 0)
                termId = termMatches[0].Id;

            return termId;

        }

        public string LookupTwitterUPS(string twitter)
        {
            Microsoft.SharePoint.Client.Search.Query.KeywordQuery q = new Microsoft.SharePoint.Client.Search.Query.KeywordQuery(ctx);
            q.QueryText = twitter + " AND contentclass:urn:content-class:SPSPeople";
            q.BypassResultTypes = true;            

            SearchExecutor searchExecutor = new Microsoft.SharePoint.Client.Search.Query.SearchExecutor(ctx);
            ClientResult<ResultTableCollection> results = searchExecutor.ExecuteQuery(q);
            ctx.ExecuteQuery();

            string userName = "";

            foreach (var resultRow  in results.Value[0].ResultRows)
            {
                //try to get the user profile id...
                userName = resultRow["AccountName"].ToString();
            }

            return userName;
        }
        

        public void SetDates(List twitterList, int itemid)
        {
            Microsoft.SharePoint.Client.ListItem li = twitterList.GetItemById(itemid.ToString());
            ctx.Load(li);
            ctx.ExecuteQuery();
            
            Field field = twitterList.Fields.GetByInternalNameOrTitle("Hashtags") as Field;
            ctx.Load(field);
            ctx.ExecuteQuery();
            TaxonomyField hashField = ctx.CastTo<TaxonomyField>(field);
            List<string> users = new List<string>();

            foreach(string mention in td.Mentions.Keys)
            {
                string user = LookupTwitterUPS(mention);                

                util.CreateUser(mention);

                if (user == null || user == "")
                    user = mention;

                if (user != null && user != "")
                    users.Add(user);
            }

            string userStr = "";
            User u;
            
            foreach (string username in users)
            {
                u = ctx.Web.EnsureUser(username);
                ctx.Load(u);
                ctx.ExecuteQuery();

                if (u != null)
                {
                    userStr += u.Id + ";#" + u.LoginName + ";#";
                    Util util = new Util();
                    ShareItem(twitterList, li, u);
                }
            }            

            string termValueString1 = "";
            string termValueString2 = "";
            List<string> termValues = new List<string>();
            int count = 0;                        

            foreach (string term in td.Hashtags.Keys)
            {
                Guid id = CreateTerm(term);

                TaxonomyFieldValue val = new TaxonomyFieldValue();
                val.Label = term;
                val.TermGuid = id.ToString();

                termValueString1 += "-1;#" + term + "|" + id + ";#";
                termValueString2 += term + "|" + id + ";";
                //termValues.Add("-1;#" + term + "|" + id);
                termValues.Add(term + "|" + id);
                count++;
            }
            
            if (termValueString1 != "")
                termValueString1 = termValueString1.Substring(0, termValueString1.Length - 2);

            if (termValueString2 != "")
                termValueString2 = termValueString2.Substring(0, termValueString2.Length - 1);                        

            if (termValueString2 != "")
            {
                string hiddenName = GetTaxonomyHiddenFieldName(twitterList, "Hashtags");
                
                TaxonomyFieldValueCollection terms2 = new TaxonomyFieldValueCollection(ctx, string.Empty, field);
                terms2.PopulateFromLabelGuidPairs(termValueString2);
                ctx.Load(terms2);
                ctx.ExecuteQuery();

                li["Hashtags"] = terms2;
                li[hiddenName] = termValueString2;
            }

            string owner = LookupTwitterUPS(td.TwitterId);

            if (owner == "")
                owner = td.TwitterId;

            u = ctx.Web.EnsureUser(owner);
            ctx.Load(u);
            ctx.ExecuteQuery();
            string ownerStr = u.Id + ";#" + u.LoginName + ";#";

            ctx.Load(li);
            ctx.ExecuteQuery();
                
            li["Author"] = ownerStr;
            li["Editor"] = ownerStr;
            li["Modified"] = td.Created;
            li["Created"] = td.Created;
            li["TweetDate"] = td.Created;
            li["TwitterId"] = td.TwitterId;
            li["Mentions"] = userStr;
            li["TweetText"] = td.Text;
            li.Update();
            ctx.ExecuteQuery();            

        }

        public void ShareItem(List list, Microsoft.SharePoint.Client.ListItem listitem, User user)
        {
            ctx.Load(list);
            ctx.Load(listitem);
            ctx.ExecuteQuery();

            string url = "https://cjg.sharepoint.com/_layouts/15/aclinv.aspx?forSharing=1&mbypass=1&List={" + list.Id + "}&obj={" + list.Id + "}%2c" + listitem.Id + "%2cDOCUMENT&IsDlg=1";

            string authCookie = "Cookie: " + creds.GetAuthenticationCookie(new Uri("https://cjg.sharepoint.com"));
            string res = util.DoGet(url, authCookie);

            string digest = util.ParseValue(res, "id=\"__REQUESTDIGEST\" value=\"", "\"");
            string viewState = util.ParseValue(res, "id=\"__VIEWSTATE\" value=\"", "\"");
            string sideBySideToken = util.ParseValue(res, "id=\"SideBySideToken\" value=\"", "\"");
            string viewStateGen = util.ParseValue(res, "id=\"__VIEWSTATEGENERATOR\" value=\"", "\"");
            string eventValidation = util.ParseValue(res, "id=\"__EVENTVALIDATION\" value=\"", "\"");
            string action = util.ParseValue(res, "<form method=\"post\" action=\"", "\"").Replace("&amp;", "&");

            digest = System.Web.HttpUtility.UrlEncode(digest);
            viewState = System.Web.HttpUtility.UrlEncode(viewState);
            eventValidation = System.Web.HttpUtility.UrlEncode(eventValidation);

            string[] vals = user.LoginName.Split('|');
            //user.LoginName
              //  user.Email
            string peoplePicker = "[{\"Key\":\"" + user.LoginName +"\",\"Description\":\"" + vals[2] + "\",\"DisplayText\":\"" + user.Title + "\",\"EntityType\":\"" + user.PrincipalType+"\",\"ProviderDisplayName\":\"Tenant\",\"ProviderName\":\"Tenant\",\"IsResolved\":true,\"EntityData\":{\"Title\":\"\",\"MobilePhone\":\"\",\"Department\":\"\",\"Email\":\"\"},\"MultipleMatches\":[],\"AutoFillKey\":\"" + user.LoginName + "\",\"AutoFillDisplayText\":\"" + user.Title +"\",\"AutoFillSubDisplayText\":\"\",\"AutoFillTitleText\":\"Tenant\\n" + vals[2] +"\",\"DomainText\":\"cjg.sharepoint.com\",\"Resolved\":true}]";
            //peoplePicker = "[{\"Key\":\"i:0#.f|membership|givenscj@cjg.onmicrosoft.com\",\"Description\":\"givenscj@cjg.onmicrosoft.com\",\"DisplayText\":\"Chris Givens\",\"EntityType\":\"User\",\"ProviderDisplayName\":\"Tenant\",\"ProviderName\":\"Tenant\",\"IsResolved\":true,\"EntityData\":{\"Title\":\"CEO\",\"MobilePhone\":\"+1 206-890-6808\",\"Department\":\"Executive\",\"Email\":\"givenscj@cjg.onmicrosoft.com\"},\"MultipleMatches\":[],\"AutoFillKey\":\"i:0#.f|membership|givenscj@cjg.onmicrosoft.com\",\"AutoFillDisplayText\":\"Chris Givens\",\"AutoFillSubDisplayText\":\"CEO\",\"AutoFillTitleText\":\"givenscj@cjg.onmicrosoft.com\nTenant\ngivenscj@cjg.onmicrosoft.com\",\"DomainText\":\"cjg.sharepoint.com\",\"Resolved\":true,\"LocalSearchTerm\":\"givenscj\"}]";

            string post = "MSOWebPartPage_PostbackSource=&MSOTlPn_SelectedWpId=&MSOTlPn_View=0&MSOTlPn_ShowSettings=False&MSOGallery_SelectedLibrary=&MSOGallery_FilterString=&MSOTlPn_Button=none&__EVENTTARGET=ctl00%24PlaceHolderMain%24btnShare&__EVENTARGUMENT=&MSOSPWebPartManager_DisplayModeName=Browse&MSOSPWebPartManager_ExitingDesignMode=false&MSOWebPartPage_Shared=&MSOLayout_LayoutChanges=&MSOLayout_InDesignMode=&MSOSPWebPartManager_OldDisplayModeName=Browse&MSOSPWebPartManager_StartWebPartEditingName=false&MSOSPWebPartManager_EndWebPartEditing=false&_maintainWorkspaceScrollPosition=0"
                + "&__REQUESTDIGEST=" + digest + "&SideBySideToken=" + sideBySideToken + "&__VIEWSTATE=" + viewState
                + "&__VIEWSTATEGENERATOR=" + viewStateGen + "&__SCROLLPOSITIONX=0&__SCROLLPOSITIONY=0&__EVENTVALIDATION=" + eventValidation 
                + "&ctl00%24PlaceHolderMain%24peoplePicker=" + peoplePicker
                + "&ctl00%24PlaceHolderMain%24DdlSimplifiedRoles=role%3A1073741826&ctl00%24ctl70%24HelpPanelSearchTextBox=Search+help+and+community";

            //Util.headers.Add("Referrer", "https://cjg.sharepoint.com/_layouts/15/" + action);
            //Util.headers.Add("Origin", "https://cjg.sharepoint.com");
            util.contentTypeOverride = "application/x-www-form-urlencoded";
            //Util.acceptOverride = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            res = util.DoPost("https://cjg.sharepoint.com/_layouts/15/" + action, post, authCookie);            
        }
        public string GetTaxonomyHiddenFieldName(List list, string internalName)
        {
            //initialization
            if (!list.IsObjectPropertyInstantiated("Fields"))
            {
                //load fields
                ctx.Load(list.Fields,
                ff => ff.Include(
                f => f.Id,
                f => f.InternalName));
                ctx.ExecuteQuery();
            }

            //get target field
            Field field = list.Fields.GetByInternalNameOrTitle(internalName);
            if (field == null)
                return string.Empty;
            
            //get taxonomy field
            TaxonomyField taxField = ctx.CastTo<TaxonomyField>(field);
            ctx.Load(taxField, f => f.TextField);
            ctx.ExecuteQuery();
            
            //get note field
            Field noteField = list.Fields.GetById(taxField.TextField);
            if (noteField == null)
                return string.Empty;

            ctx.Load(noteField);
            ctx.ExecuteQuery();                
            
            //return
            return noteField.InternalName;
        }
        public void SetProperty(Web w, string key, string value)
        {
            PropertyValues pv = w.AllProperties;
            w.Context.Load(pv);
            w.Context.ExecuteQuery();
            
            object customProp = null;

            if (pv.FieldValues.ContainsKey(key))
                customProp = pv.FieldValues[key];

            if (customProp != null)
            {
                int val = int.Parse(customProp.ToString());
                val += 1;
                pv.FieldValues[key] = val;
            }
            else
            {
                pv.FieldValues.Add(key, value);
            }

            w.Update();
            w.Context.ExecuteQuery();
        }


        public void ReplaceDocument(string fileName, string document)
        {
            Package pkg = Package.Open(fileName);

            Uri uri = null;
            PackagePart pp = null;

            try
            {
                uri = new Uri("/word/document.xml", UriKind.Relative);
                pp = pkg.GetPart(uri);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Stream s = null;
                StreamWriter sw = null;
                if (pp != null)
                {
                    s = pp.GetStream();
                    s.Flush();
                    sw = new StreamWriter(s);
                    sw.Write(document);
                    sw.Close();
                }

                pkg.Close();
            }

        }

        public wp CreatePForImage(string imagePath, int pageNumber, int pixelWidth, int pixelHeight)
        {
            int emuWidth = pixelWidth * 9525;
            int emuHeight = pixelHeight * 9525;

            wp p = new wp();
            p.PId = null;
            p.RsidP = null;
            p.RsidR = null;
            p.RsidRDefault = null;
            p.RsidRPr = null;
            p.WsmartTags = null;

            wr r = new wr();
            r.RId = null;
            r.RsidR = null;
            r.RsidRPr = null;
            wrPr rPr = new wrPr();
            rPr.RPrId = null;
            rPr.Wlangs = null;
            rPr.WrFontss = null;
            rPr.WrStyles = null;
            wnoProof noProof = new wnoProof();
            rPr.WnoProof = noProof;
            r.WrPr = rPr;

            wdrawing drawing = new wdrawing();
            drawing.DrawingId = null;
            wpinline inline = new wpinline();
            inline.InlineId = null;
            inline.DistT = "0";
            inline.DistB = "0";
            inline.DistL = "0";
            inline.DistR = "0";
            wpextent extent = new wpextent();
            extent.Cx = emuWidth.ToString();
            extent.Cy = emuHeight.ToString();
            inline.Wpextent = extent;
            wpeffectExtent effectExtent = new wpeffectExtent();
            effectExtent.L = "0";
            effectExtent.T = "0";
            effectExtent.R = "0";
            effectExtent.B = "0";
            inline.WpeffectExtent = effectExtent;
            wpdocPr docPr = new wpdocPr();

            docPr.Id = pageNumber.ToString();

            docPr.Name = "Picture " + pageNumber.ToString();
            docPr.Descr = imagePath;
            inline.WpdocPr = docPr;
            wpcNvGraphicFramePr cNvGraphicFramePr = new wpcNvGraphicFramePr();
            cNvGraphicFramePr.CNvGraphicFramePrId = null;
            agraphicFrameLocks graphicFrameLocks = new agraphicFrameLocks();
            graphicFrameLocks.A = null;
            graphicFrameLocks.NoChangeAspect = "1";
            cNvGraphicFramePr.AgraphicFrameLocks = graphicFrameLocks;
            inline.WpcNvGraphicFramePr = cNvGraphicFramePr;

            agraphic graphic = new agraphic();
            graphic.A = null;
            graphic.GraphicId = null;
            agraphicData graphicData = new agraphicData();
            graphicData.GraphicDataId = null;
            graphicData.Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture";
            picpic pic = new picpic();
            pic.PicId = null;
            pic.Pic = null;
            picnvPicPr nvPicPr = new picnvPicPr();
            nvPicPr.NvPicPrId = null;
            piccNvPr cNvPr = new piccNvPr();
            cNvPr.Id = "0";
            cNvPr.Name = "Picture " + pageNumber.ToString();
            cNvPr.Descr = imagePath;
            nvPicPr.PiccNvPr = cNvPr;
            piccNvPicPr cNvPicPr = new piccNvPicPr();
            cNvPicPr.PreferRelativeResize = "0";
            cNvPicPr.CNvPicPrId = null;
            apicLocks picLocks = new apicLocks();
            picLocks.NoChangeAspect = "1";
            picLocks.NoChangeArrowheads = "1";
            cNvPicPr.ApicLocks = picLocks;
            nvPicPr.PiccNvPicPr = cNvPicPr;
            pic.PicnvPicPr = nvPicPr;

            picblipFill blipFill = new picblipFill();
            blipFill.BlipFillId = null;
            ablip blip = new ablip();

            int id = pageNumber + 13;
            blip.Embed = "rId" + id.ToString();

            blipFill.Ablip = blip;
            astretch strech = new astretch();
            strech.StretchId = null;
            afillRect fillRect = new afillRect();
            strech.AfillRect = fillRect;
            blipFill.Astretch = strech;
            asrcRect srcRect = new asrcRect();
            blipFill.AsrcRect = srcRect;

            pic.PicblipFill = blipFill;

            picspPr spPr = new picspPr();
            spPr.SpPrId = null;
            spPr.BwMode = "auto";

            axfrm xfrm = new axfrm();
            xfrm.XfrmId = null;
            aoff off = new aoff();
            off.X = "0";
            off.Y = "0";
            aext ext = new aext();
            ext.Cx = emuWidth.ToString(); ;
            ext.Cy = emuHeight.ToString(); ;
            xfrm.AchExt = null;
            xfrm.AchOff = null;
            xfrm.Aext = ext;
            xfrm.Aoff = off;
            spPr.Axfrm = xfrm;

            aprstGeom prstGeom = new aprstGeom();
            prstGeom.PrstGeomId = null;
            prstGeom.Prst = "rect";
            aavLst avLst = new aavLst();
            prstGeom.AavLst = avLst;
            spPr.AprstGeom = prstGeom;

            anoFill noFill = new anoFill();
            spPr.AnoFill = noFill;

            aln ln = new aln();
            ln.LnId = null;
            ln.W = "9525";
            ln.AnoFill = noFill;
            amiter miter = new amiter();
            miter.Lim = "800000";
            ln.Amiter = miter;
            aheadEnd headEnd = new aheadEnd();
            ln.AheadEnd = headEnd;
            atailEnd tailEnd = new atailEnd();
            ln.AtailEnd = tailEnd;
            spPr.Aln = ln;

            pic.PicspPr = spPr;
            graphicData.Picpic = pic;
            graphic.AgraphicData = graphicData;
            inline.Agraphic = graphic;
            drawing.Wpinline = inline;

            r.Wdrawing = drawing;
            p.Wrs.Add(r);

            return p;
        }

        public void CreateWordDocumentBody(out wdocument doc, out wbody body)
        {
            //create a document!
            doc = new wdocument();
            doc.DocumentId = null;
            doc.M = null;
            doc.O = null;
            doc.R = null;
            doc.V = null;
            doc.Ve = null;
            doc.W = null;
            doc.W10 = null;
            doc.Wp = null;
            doc.Wne = null;
            body = new wbody();
            body.BodyId = null;
            body.WsectPr = null;
        }

        public void CreateEmptyDoc(string name)
        {
            System.IO.File.Delete(name);

            using (WordprocessingDocument package = WordprocessingDocument.Create(name, WordprocessingDocumentType.Document))
            {
                // Add a new main document part. 
                package.AddMainDocumentPart();

                // Create the Document DOM. 
                package.MainDocumentPart.Document =
                  new Document(
                    new Body(
                      new Paragraph(
                        new Run())));


                // Save changes to the main document part. 
                package.MainDocumentPart.Document.Save();
            }
        }

         public string imageRel = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";

         public void AddImageIntoWord(Package pkg, int id, int relationId, byte[] file)
        {
            PackagePart pp = GetPackagePart(pkg, "/word/media/image" + id.ToString() + ".png");

            if (pp == null)
            {
                CreatePackagePart(pkg, "/word/media/image" + id.ToString() + ".png", "image/png", file);
                CreatePackageRelationship(GetOfficeXmlDocumentPackagePart(pkg), "media/image" + id.ToString() + ".png", imageRel, "rId" + relationId.ToString());
            }
            else
            {
                UpdatePackagePart(pp, file);
            }
        }

         public PackagePart GetOfficeXmlDocumentPackagePart(Package pkg)
        {
            return GetPackagePart(pkg, "/word/document.xml");
        }

         public PackagePart GetPackagePart(Package pkg, string uri)
        {
            PackagePart part = null;
            try
            {
                part = pkg.GetPart(new Uri(uri, UriKind.Relative));
            }
            catch (Exception ex)
            {
            }

            return part;
        }

         public PackagePart UpdatePackagePart(PackagePart part, byte[] file)
        {
            if (part != null)
            {
                Stream partStream = part.GetStream(FileMode.Create, FileAccess.Write);
                partStream.Write(file, 0, file.Length);
            }

            return part;
        }

         public PackagePart CreatePackagePart(Package pkg, string uri, string contentType, byte[] file)
        {
            PackagePart part = null;

            if (file != null)
            {
                part = pkg.CreatePart(new Uri(uri, UriKind.Relative), contentType);
                Stream partStream = part.GetStream(FileMode.Create, FileAccess.Write);
                BinaryWriter bw = new BinaryWriter(partStream);
                bw.Write(file);
            }

            return part;
        }

         public PackageRelationship CreatePackageRelationship(PackagePart pkg, string uri, string relType, string id)
        {
            Uri test = new Uri(uri, UriKind.Relative);

            //Create a Uri for the document part.
            Uri partURI = PackUriHelper.CreatePartUri(
                   new Uri(uri,
                   UriKind.Relative));

            //Create a relationship between the document part and the package.
            return pkg.CreateRelationship(test, TargetMode.Internal, relType, id);
        }
    }
}
